package ar.edu.unlu.sistemas.p2p.business.util;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;

import ar.edu.unlu.sistemas.p2p.business.exception.MovirdroidException;
import ar.edu.unlu.sistemas.p2p.business.exception.MovirdroidExceptionMessages;

public class Params {
	
	//Properties
	public static int WAITING_TASK_ITERATIONS = 10000;
	
	public static int TCP_LISTEN_PORT = 3600;
	
	public static int MSG_TTL = 5;
	
	public static boolean USE_WORDS_CACHE = false;
	
	public static float THRESHOLD = (float) 0.6;
	
	public static String CORPUS_DIR = "corpus";
	
	public static String PEER_ALIAS = "movirdroid_user";
	
	public static boolean PROCESS_QUERY_PERFORMED = true;
	
	public static boolean BOOLEAN_EXTENDED_MODE = false;
	
	public static int MIN_LENGHT = 2;
	
	public static int MIN_FRECUENCY = 3;
	
	private static Document createConfigFile() {
		Element el = new Element(Constants.CONFIG_FILE_ROOT_TAG);
		Map<String,String> prefMap = getMapPreferences();
		Iterator<String> prefMapIt = prefMap.keySet().iterator();
		String key;
		while (prefMapIt.hasNext()) {
			key = prefMapIt.next();
			el.addContent(new Element(key).setText(prefMap.get(key)));
		}
		Document doc = new Document();
		doc.addContent(el);
		return doc;
	}
	
	private static void setValueOfField(String fieldName, String fieldValue) {
		try {
			Field field = Params.class.getField(fieldName);
			if ("int".equals(field.getType().getName())) {
				field.set(null, new Integer(fieldValue).intValue());
			} else if ("long".equals(field.getType().getName())){
				field.set(null, new Long(fieldValue).longValue());
			} else if ("short".equals(field.getType().getName())){
				field.set(null, new Short(fieldValue).shortValue());
			} else if ("byte".equals(field.getType().getName())){
				field.set(null, new Byte(fieldValue).byteValue());
			} else if ("double".equals(field.getType().getName())){
				field.set(null, new Double(fieldValue).doubleValue());
			} else if ("float".equals(field.getType().getName())){
				field.set(null, new Float(fieldValue).floatValue());
			} else if ("boolean".equals(field.getType().getName())){
				field.set(null, new Boolean(fieldValue).booleanValue());
			} else {
				field.set(null,fieldValue);
			}
		} catch (IllegalAccessException iae) {
			
		} catch (NoSuchFieldException nsfe) {
			
		}
	}
	
	public static void loadParamsFromFile(Document xmlDocument) {
		if (xmlDocument != null) {
			Element root = xmlDocument.getRootElement();
			Iterator<Element> children = root.getChildren().iterator();
			Element child;
			while (children.hasNext()) {
				child = children.next();
				setValueOfField(child.getName(), child.getText());
			}
		}
	}
	
	public static void savePreferences(FileOutputStream fos) throws MovirdroidException{
		try {
			fos.write(XMLManager.getInstance().xmlDocToString(createConfigFile()).getBytes("UTF-8"));
			fos.close();
		} catch (IOException ioe) {
			throw new MovirdroidException(MovirdroidExceptionMessages.ERROR_SAVING_CONFIG);
		}
	}
	
	public static void loadPreferences(FileInputStream fis) throws MovirdroidException{
		try {
			String fileContent = ByteHelper.readTextFile(fis,"UTF-8");
			Logger.logDebug(Params.class.getSimpleName(),fileContent);
			Document xmlDoc = XMLManager.getInstance().buildXMLDocFromString(fileContent);
			loadParamsFromFile(xmlDoc);
		} catch (IOException ioe) {
			Logger.logError(Params.class.getSimpleName(), ioe.getMessage(), ioe);
			throw new MovirdroidException(MovirdroidExceptionMessages.ERROR_LOADING_CONFIG);
		}
	}
	
	public static Map<String,String> getMapPreferences() {
		Map<String,String> prefMap = new HashMap<String,String>();
		Iterator<Field> fields = Arrays.asList(Params.class.getFields()).iterator();
		Field field;
		while (fields.hasNext()) {
			field = fields.next();
			try {
				prefMap.put(field.getName(),String.valueOf(field.get(null)));
			} catch (IllegalAccessException iae) {
				prefMap.put(field.getName(),null);
			}
		}
		return prefMap;
	}
	
	public static void setMapPreferences(Map<String,String> prefMap) {
		Iterator<String> keys = prefMap.keySet().iterator();
		String key;
		while (keys.hasNext()) {
			key = keys.next();
			setValueOfField(key, prefMap.get(key));
		}
	}
	
}
